#ifndef ETCD_CLIENT_H
#define ETCD_CLIENT_H

#include <string>
#include <vector>
#include <functional>
#include <curl/curl.h>

// 前向声明
struct CurlResponseData;

// ETCD操作结果
struct EtcdResult {
    bool success;                                   // 操作是否成功
    std::string value;                              // 操作结果值（如果有）
    std::string errorMessage;                       // 错误信息（如果有）
    std::vector<std::pair<std::string, std::string>> kvs; // 键值对列表（用于前缀查询）
};

/**
 * ETCD客户端类
 * 负责与ETCD服务器通信
 */
class EtcdClient {
public:
    /**
     * 构造函数
     * @param url ETCD服务器URL
     */
    EtcdClient(const std::string& url);
    
    /**
     * 析构函数
     */
    ~EtcdClient();
    
    /**
     * 初始化
     * @return 是否成功
     */
    bool init();
    
    /**
     * 存储键值对
     * @param key 键
     * @param value 值
     * @param leaseId 租约ID（可选）
     * @return 操作结果
     */
    EtcdResult put(const std::string& key, const std::string& value, int64_t leaseId = 0);
    
    /**
     * 获取键值
     * @param key 键
     * @return 操作结果，value字段包含值
     */
    EtcdResult get(const std::string& key);
    
    /**
     * 删除键
     * @param key 键
     * @return 操作结果
     */
    EtcdResult del(const std::string& key);
    
    /**
     * 按前缀获取键值
     * @param prefix 前缀
     * @return 操作结果，kvs字段包含键值对列表
     */
    EtcdResult getPrefix(const std::string& prefix);
    
    /**
     * 创建租约
     * @param ttl 生存时间（秒）
     * @return 操作结果，value字段包含租约ID
     */
    EtcdResult grantLease(int ttl);
    
    /**
     * 续约
     * @param leaseId 租约ID
     * @return 操作结果
     */
    EtcdResult keepAliveLease(int64_t leaseId);
    
    /**
     * 撤销租约
     * @param leaseId 租约ID
     * @return 操作结果
     */
    EtcdResult revokeLease(int64_t leaseId);
    
    /**
     * 执行事务
     * @param compareKey 比较键
     * @param compareValue 比较值
     * @param compareEqual 是否比较相等
     * @param successKey 成功时操作的键
     * @param successValue 成功时操作的值
     * @param leaseId 租约ID（可选）
     * @return 操作结果
     */
    EtcdResult txn(const std::string& compareKey, const std::string& compareValue, 
                  bool compareEqual, const std::string& successKey, 
                  const std::string& successValue, int64_t leaseId = 0);
    
    /**
     * 观察键
     * @param key 键
     * @param callback 回调函数，参数为(键，值，是否删除)
     * @return 操作结果
     */
    EtcdResult watch(const std::string& key, std::function<void(const std::string&, const std::string&, bool)> callback);
    
    /**
     * 观察前缀
     * @param prefix 前缀
     * @param callback 回调函数，参数为(键，值，是否删除)
     * @return 操作结果
     */
    EtcdResult watchPrefix(const std::string& prefix, std::function<void(const std::string&, const std::string&, bool)> callback);

private:
    /**
     * 执行HTTP请求
     * @param url URL
     * @param requestBody 请求体
     * @param responseData 响应数据
     * @return CURL结果代码
     */
    CURLcode performRequest(const std::string& url, const std::string& requestBody, CurlResponseData& responseData);
    
    /**
     * Base64编码
     * @param input 输入字符串
     * @return 编码后的字符串
     */
    std::string base64Encode(const std::string& input);
    
    /**
     * Base64解码
     * @param input 输入字符串
     * @return 解码后的字符串
     */
    std::string base64Decode(const std::string& input);
    
    /**
     * 获取范围结束键
     * @param prefix 前缀
     * @return 范围结束键
     */
    std::string getEndKey(const std::string& prefix);

private:
    std::string m_url;      // ETCD服务器URL
};

#endif // ETCD_CLIENT_H 